﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xna.Framework;
using WarriorRush.UserInterface;
using WarriorRush.GameDynamics.Utilities;

namespace WarriorRush.GameDynamics
{
    public class Arena
    {
        public List<List<ArenaSquare>> Squares;
        public List<SimplePoint> ReplaceMentPositon;

        public Arena()
        {
            ReplaceMentPositon = new List<SimplePoint>{
                new SimplePoint(-1,0),
                new SimplePoint(-1,1),
                new SimplePoint(-1,-1)
            };
            Squares = new List<List<ArenaSquare>>();
            for (int n = 0; n < 4; n++)
            {
                var newRow = new List<ArenaSquare>();

                for (int m = 0; m < 5; m++)
                {
                    var arenaSquare = new ArenaSquare( n,  m );
                    newRow.Add(arenaSquare);
                }
                Squares.Add(newRow);
            }
            SetupSquareRelations();
        }

        public void SlideSide(int pivotPoint, int direction, int player)
        {
            var backRow = player == 1 ? 0 : 3;

            for (int n = pivotPoint; n > 0 && n < Squares[player].Count; n += direction)
            {
                var nextIndex = n + direction;
                if (nextIndex >= Squares[player].Count || nextIndex < 0 )
                    continue;
                var currentSquare = Squares[player][n];
                var nextSquare = Squares[player][nextIndex];
               
                currentSquare.Character = nextSquare.Character;
                nextSquare.Character = null;

                currentSquare = Squares[backRow][n];
                nextSquare = Squares[backRow][nextIndex];
                currentSquare.Character = nextSquare.Character;
                nextSquare.Character = null;

            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="origin">The original attack</param>
        /// <param name="spaces">The additional targets by offset</param>
        /// <returns></returns>
        public List<ArenaSquare> GetTargetedSpaces(ArenaSquare origin, List<SimplePoint> spaces, bool GetOnlyCharacterSquares)
        {
            var targetSquares = new List<ArenaSquare>();
            var direction = origin.Row == 1? 1: -1;
            if (spaces == null)
                return null;
            foreach (var space in spaces)
            {
                int row, col;
                row = origin.Row + (direction * space.RowOffset);
                col = origin.Column + (direction * space.ColOffset);
                if (row < 0 || col < 0 || row >= Squares.Count || col >= Squares[row].Count)
                    continue;
                if (!GetOnlyCharacterSquares || Squares[row][col].Character!= null)
                    targetSquares.Add(Squares[row][col]);
            }

            return targetSquares;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="square"></param>
        public void Pivot(Player player)
        {
            CloseGaps(player);
            Center(player);
        }


        public bool CheckIfCharacterHasReplacement(CharacterClass character)
        {
           return GetTargetedSpaces(character.Square, ReplaceMentPositon, true).Any();

        }
        private void CloseGaps(Player player)
        {
            var index = 0;
            var deadCharacters = GetDeadCharacters((int)player + 1);
            
            foreach (var charPosition in deadCharacters)
            {
                var deadSquare = charPosition.Square;
                if(deadSquare.Column==0 || deadSquare.Column == 4)
                {
                    index++;
                    deadSquare.Character = null;
                   // var squareBehind = Squares[rowBehind][deadSquare.Column];
                    //if(squareBehind.Character != null)


                    continue;
                }
                SlideSide(deadSquare.Column, 1, (int)player + 1);
               
            }


        }

        private void Center(Player player)
        {
            var playerRows = getRowsForPlayer(player);
            if(Squares[playerRows.X].Any(f=>f.HasWarrior))
            {
                var squareFromStart =  Squares[playerRows.X].First(f=>f.HasWarrior).Column;
                var squaresFromEnd = 4 - Squares[playerRows.X].Last(f => f.HasWarrior).Column;
                var difference =   squaresFromEnd - squareFromStart;

                if (Math.Abs(difference) > 1)
                {
                    for (var n = Math.Abs(difference); n > 1; n--)
                    {
                        var point = difference > 0 ? squaresFromEnd + 1 : squareFromStart - 1;
                        SlideSide(point, Math.Sign(difference) * -1 , playerRows.X);
                        squaresFromEnd++;
                        squareFromStart--;
                    }
                   

                }

                var lastSquareAtTheEnd = Squares[playerRows.X].Last(f => f.HasWarrior);
                var firstSquareAtEnd = Squares[playerRows.X].First(f => f.HasWarrior);

                if (lastSquareAtTheEnd.Behind.HasWarrior && lastSquareAtTheEnd.Below != null)
                    lastSquareAtTheEnd.Behind.MoveCharacterToSquare(lastSquareAtTheEnd.Below);
                if (firstSquareAtEnd.Behind.HasWarrior && firstSquareAtEnd.Above != null)
                    firstSquareAtEnd.Behind.MoveCharacterToSquare(firstSquareAtEnd.Above);


            }
        }

        private Point getRowsForPlayer(Player player)
        {
            return new Point((int)player + 1, player == Player.one ? 0 : 3);
        }
        public SelectionHandler GetSelectables(ArenaSquare origin, List<SimplePoint> spaces, bool GetOnlyCharacterClasses, HighlightType type)
        {
            return new SelectionHandler
            {
                Squares = GetTargetedSpaces(origin, spaces, true).Where(f=>!GetOnlyCharacterClasses || f.Character != null)
                      .Select(f => new Selectable() { Square = f }).ToList(),
                SelectType = type,
                IsReplacedSelection = true,
                MaxSelections = 1
            };
        }

        public List<CharacterClass> GetDeadCharacters(int row)
        {
            return Squares[row].Where(f => f.Character != null && f.Character.IsDead).Select(f=>f.Character).ToList();
        }

        public SelectionHandler GetReplacements(ArenaSquare origin)
        {

            return GetSelectables(origin, ReplaceMentPositon, true, HighlightType.Selectable);
        }


        private void SetupSquareRelations()
        {
            for (int n = 0; n < 4; n++)
            {
                for (int m = 0; m < 5; m++)
                {
                    var currentsquare = Squares[n][m];
                    if(n==1)
                        currentsquare.Behind = Squares[0][m];
                    if (n == 2)
                        currentsquare.Behind = Squares[3][m];

                    if (m > 0)
                        currentsquare.Above = Squares[n][m - 1];

                    if(m < 4)
                        currentsquare.Below = Squares[n][m + 1];

                }

            }
        }

      

    }
}
